﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows;

namespace Net.Chirash.Twitter.TweetZone.WindowComponents.ViewModels
{
    /// <summary>
    /// Container系のViewModel基底クラス。
    /// </summary>
    public abstract class ContainerViewModelBase
        : INotifyPropertyChanged
    {
        /// <summary>
        /// 更新処理を同期的に行います
        /// </summary>
        public abstract void Refresh();

        /// <summary>
        /// 更新処理を非同期的に行います
        /// </summary>
        /// <param name="completed">更新処理が終了した際に呼び出されるAction。null指定で何も呼び出しません。</param>
        public abstract void RefreshAsync(Action<ContainerViewModelBase> completed);

        #region public ErrorMessage LastErrorMessage { get; set; }
        private ErrorMessage _LastErrorMessage;
        public ErrorMessage LastErrorMessage
        {
            get { return _LastErrorMessage; }
            set { _LastErrorMessage = value; OnPropertyChanged("LastErrorMessage"); }
        }
        #endregion

        public ContainerComposer Composer { get; set; }

        #region helper function

        /// <summary>
        /// 関連付けられたComposerのDispatcher、もしくは現在関連付けられているSynchronizationContextを使用してActionを実行します。
        /// InvalidOperationExceptionがスローされる可能性があります(View消失時など)。
        /// </summary>
        /// <param name="act">実行するAction</param>
        protected void InvokeByComposerIfNeeded(Action act)
        {
            if (Composer != null)
            {
                //Console.WriteLine("ComposerInvoke");
                Composer.SafeInvoke(act);
            }
            else
            {
                //Console.WriteLine("TaskSchedulerInvoke");
                var task = new System.Threading.Tasks.Task(act);
                task.RunSynchronously(System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext());
            }
        }

        #endregion

        public virtual void TaskSubscribe() { }
        public virtual void UnSubscribe() { }

        #region Implementation of INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }

        #endregion


    }
}
